package domain

import (
	"github.com/lab-online/internal/class/entity"
	"github.com/lab-online/internal/shared/valueobject"
	"github.com/lab-online/pkg/auth"
	"github.com/lab-online/pkg/util"
	"golang.org/x/exp/slices"
)

func (d *Domain) SearchClass(
	classEntity entity.ClassEntity, authEntity auth.AuthEntity,
) ([]entity.ClassEntity, error) {
	if classes, err := d.repository.GetClasses(classEntity); err != nil {
		return nil, err
	} else {
		teachers := util.SliceMap(classes, func(classEntity entity.ClassEntity) string {
			return classEntity.GetTeacher()
		})
		teacherVOs, dbErr := d.userRepository.GetManyUsersByUsername(teachers)
		if dbErr != nil {
			return nil, dbErr
		}

		teacherMap := make(map[string]valueobject.UserVO, len(teacherVOs))
		for _, teacher := range teacherVOs {
			teacherMap[teacher.GetUsername()] = teacher
		}

		for _, class := range classes {
			if teacher, ok := teacherMap[class.GetTeacher()]; ok {
				class.UpdateEntity(entity.WithTeacherVO(teacher))
			}
		}

		classIDs, err := d.repository.GetClassIDsForStudent(authEntity.GetUsername())
		if err != nil {
			return nil, err
		}

		return util.SliceFilter(classes, func(classEntity entity.ClassEntity) bool {
			return classEntity.CanHandleClass(authEntity, true) ||
				slices.Contains(classIDs, classEntity.GetID())
		}), nil
	}
}
